Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Promises to RTMClient start and disconnect #611

Merged
merged 3 commits into from
Aug 24, 2018

Conversation

clavin
Copy link
Contributor

@clavin clavin commented Aug 9, 2018

Summary

Fixes #198 and #610:

  • Fixes the RTM connecting submachine to transition to a failed state, which emits a failure event on the parent machine, allowing for the disconnected state to be reached from a failure to reconnect (tl;dr: it works 馃憤)
  • Changes the return types of RTMClient#start to Promise<WebAPICallResult> and RTMClient#disconnect to Promise<void>

Requirements

@codecov
Copy link

codecov bot commented Aug 9, 2018

Codecov Report

Merging #611 into master will increase coverage by 3.18%.
The diff coverage is 94.87%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master     #611      +/-   ##
==========================================
+ Coverage   88.83%   92.01%   +3.18%     
==========================================
  Files           7        7              
  Lines         421      426       +5     
  Branches       73       78       +5     
==========================================
+ Hits          374      392      +18     
+ Misses         31       19      -12     
+ Partials       16       15       -1
Impacted Files Coverage 螖
src/methods.ts 100% <酶> (酶) 猬嗭笍
src/WebClient.ts 94.4% <100%> (+2.28%) 猬嗭笍
src/IncomingWebhook.ts 87.09% <71.42%> (+21.38%) 猬嗭笍

Continue to review full report at Codecov.

Legend - Click here to learn more
螖 = absolute <relative> (impact), 酶 = not affected, ? = missing data
Powered by Codecov. Last update 842c7a7...ddadd39. Read the comment docs.

// delegate behavior to state machine
this.stateMachine.handle('explicit disconnect');
// delegate behavior to state machine
this.stateMachine.handle('explicit disconnect');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

any reason to kick this event off inside the returned Promise's constructor, as opposed to the line before the return statement?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the web socket immediately errors on closing (that is, on the same tick of the event loop as handle is called) then the event handler won't be registered by the time the state machine transitions, and the promise will never reject.

Alternatively, the web socket could also immediately close (e.g. when mocked for testing) and the same problem would happen, though the promise wouldn't resolve.

I'm just being cautious that the reactive bit of code is set up before I set off the chain reaction. Don't want any race conditions happening 馃槄

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

馃憣sounds reasonable to me!

src/RTMClient.ts Outdated
this.logger.debug(`transitioning to state: ${state}`);
// Emits events: `disconnected`, `connecting`, `connected`, 'disconnecting', 'reconnecting'
this.emit(state);
// event payload is anything related to the event, i.e. an error on disconnect
this.emit(state, context.eventPayload);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it seems like this could have effects greater than passing through the error on disconnect. i'd like to be a little more explicit about what this argument will contain for each kind of transition.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just looking through the code, the only other case I could see where something else passes through would be the event payloads for web socket events, specifically the non-existent open event's payload and the web socket closing code and reason from the close event.

I agree, though, that this could end up leaking something else through. Is there a better course of action? Like guarding that only eventPayload instanceof Error passes?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it seems like the intention is to only emit the context.eventPayload when transitioning to `"disconected". if that's true, i think it would be clearer to do something like:

if (state === 'disconnected') {
  // when arriving at this state due to failure, the eventPayload will contain an error.
  // otherwise, like after a force disconnect, this value will be undefined
  const errorOrUndefined = context.eventPayload;
  this.emit(state, errorOrUndefined);
} else {
  this.emit(state);
}

its more explicit, and gives us a chance to document the intention.

@aoberoi
Copy link
Contributor

aoberoi commented Aug 23, 2018

@clavin looks like we're really close! i'd like to make a release soon, since #619 adds a type definition change that would be helpful. if you're willing the address the last outstanding comment by Friday, i'll hold off for that. otherwise i'll release at latest then, and we can continue to work on getting this PR landed.

@aoberoi aoberoi merged commit fc6371c into slackapi:master Aug 24, 2018
@aoberoi
Copy link
Contributor

aoberoi commented Aug 24, 2018

thanks!

@clavin clavin deleted the issue-198-rtm-start-promise branch December 15, 2018 14:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants